package com.zhou.nio.server;

import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.DatagramChannel;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.util.Iterator;

/**
 * @descrition:简单的UDP服务器，通过DatagramChannel 和 Selector 实现
 * @author: zhouyongjun
 * @date: 2022/8/29
 **/
@Slf4j
public class UDPDatagramChannelServer {
    public static void main(String[] args) throws IOException {
        startServer();
    }

    private static void startServer() throws IOException {
        //获取数据报通道
        DatagramChannel channel = DatagramChannel.open();
        //设置非阻塞
        channel.configureBlocking(false);
        //绑定地址
        channel.socket().bind(new InetSocketAddress(18080));
        //开通一个通道选择器
        Selector selector = Selector.open();
        //讲通道注册到选择器s
        channel.register(selector, SelectionKey.OP_READ);
        //通过选择器 查询I0事件
        while (selector.select() > 0) {
            Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
            ByteBuffer buffer = ByteBuffer.allocate(1024);
            //迭代IO
            while(iterator.hasNext()) {
                SelectionKey selectionKey = iterator.next();
                if(selectionKey.isReadable()) {
                    //读取数据通道的数据
                    SocketAddress client = channel.receive(buffer);
                    buffer.flip();
                    log.info(new String(buffer.array(),0,buffer.limit())+"\t"+client);
                    buffer.clear();
                }
            }
            iterator.remove();
        }
        //关闭选择器和通道
        selector.close();
        channel.close();
    }
}
